1. Car Auction Network

Car Auction拍卖 Network

List assets for sale (setting a reserve price), and watch as assets that have met their reserve price are automatically transferred to the highest bidder at the end of the auction.

Participants: Member Auctioneer

Assets: Vehicle VehicleListing

Transactions: Offer CloseBidding

car

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
describe('#makeOffer', () => {

it('should add the offer to the offers of a vehicle listing', () => {

const factory = businessNetworkConnection.getBusinessNetwork().getFactory();

// create the auctioneer
const seller = factory.newResource(NS, 'Member', 'daniel.selman@example.com');
seller.firstName = 'Dan';
seller.lastName = 'Selman';
seller.balance = 0;

// create the vehicle
const vehicle = factory.newResource(NS, 'Vehicle', 'CAR_001');
vehicle.owner = factory.newRelationship(NS, 'Member', seller.$identifier);

// create the vehicle listing
const listing = factory.newResource(NS, 'VehicleListing', 'LISTING_001');
listing.reservePrice = 100;
listing.description = 'My nice car';
listing.state = 'FOR_SALE';
listing.vehicle = factory.newRelationship(NS, 'Vehicle', 'CAR_001');

// create the buyer
const buyer = factory.newResource(NS, 'Member', 'sstone1@example.com');
buyer.firstName = 'Simon';
buyer.lastName = 'Stone';
buyer.balance = 1000;

// create another potential buyer
const buyer2 = factory.newResource(NS, 'Member', 'whitemat@example.com');
buyer2.firstName = 'Matthew';
buyer2.lastName = 'White';
buyer2.balance = 100;

// create the auctioneer
const auctioneer = factory.newResource(NS, 'Auctioneer', 'boss@auction.com');
auctioneer.firstName = 'Mr';
auctioneer.lastName = 'Smith';

const offer = factory.newTransaction(NS, 'Offer');
offer.member = factory.newRelationship(NS, 'Member', buyer.$identifier);
offer.listing = factory.newRelationship(NS, 'VehicleListing', 'LISTING_001');
offer.bidPrice = 200;

// Get the asset registry.
return businessNetworkConnection.getAssetRegistry(NS + '.Vehicle')
.then((vehicleRegistry) => {

// Add the Vehicle to the asset registry.
return vehicleRegistry.add(vehicle)
.then(() => {
// Add the VehicleListing to the asset registry
return businessNetworkConnection.getAssetRegistry(NS + '.VehicleListing');
})
.then((vehicleListingRegistry) => {
// add the vehicle listing
return vehicleListingRegistry.add(listing);
})
.then(() => {
return businessNetworkConnection.getParticipantRegistry(NS + '.Member');
})
.then((userRegistry) => {
// add the members
return userRegistry.addAll([buyer, buyer2, seller]);
})
.then(() => {
return businessNetworkConnection.getParticipantRegistry(NS + '.Auctioneer');
})
.then((userRegistry) => {
// add the auctioneers
return userRegistry.addAll([auctioneer]);
})
.then(() => {
// Create the offer transaction and submit
return businessNetworkConnection.submitTransaction(offer);
})
.then(() => {
const lowOffer = factory.newTransaction(NS, 'Offer');
lowOffer.member = factory.newRelationship(NS, 'Member', buyer2.$identifier);
lowOffer.listing = factory.newRelationship(NS, 'VehicleListing', 'LISTING_001');
lowOffer.bidPrice = 50;
// Create the offer transaction and submit
return businessNetworkConnection.submitTransaction(lowOffer);
})
.then(() => {
return businessNetworkConnection.getAssetRegistry(NS + '.VehicleListing');
})
.then((vehicleListingRegistry) => {
// get the listing
return vehicleListingRegistry.get(listing.$identifier);
})
.then((newListing) => {
// both offers should have been added to the listing
newListing.offers.length.should.equal(2);
})
.then(() => {
// close the bidding
const closeBidding = factory.newTransaction(NS, 'CloseBidding');
closeBidding.listing = factory.newRelationship(NS, 'VehicleListing', 'LISTING_001');
return businessNetworkConnection.submitTransaction(closeBidding);
})
.then(() => {
return businessNetworkConnection.getAssetRegistry(NS + '.VehicleListing');
})
.then((vehicleListingRegistry) => {
// get the listing
return vehicleListingRegistry.get(listing.$identifier);
})
.then((newListing) => {
// the offer should have been added to the listing
newListing.state.should.equal('SOLD');
})
.then(() => {
return businessNetworkConnection.getParticipantRegistry(NS + '.Member');
})
.then((userRegistry) => {
// add the buyer and seller
return userRegistry.get(buyer.$identifier);
})
.then((buyer) => {
// check the buyer's balance
buyer.balance.should.equal(800);
})
.then(() => {
return businessNetworkConnection.getParticipantRegistry(NS + '.Member');
})
.then((userRegistry) => {
// add the buyer and seller
return userRegistry.get(seller.$identifier);
})
.then((newSeller) => {
// check the seller's balance
newSeller.balance.should.equal(200);
})
.then(() => {
return businessNetworkConnection.getParticipantRegistry(NS + '.Member');
})
.then((userRegistry) => {
// add the buyer and seller
return userRegistry.get(buyer.$identifier);
})
.then((newBuyer) => {
// check the buyer's balance
newBuyer.balance.should.equal(800);
})
.then(() => {
return businessNetworkConnection.getAssetRegistry(NS + '.Vehicle');
})
.then((vehicleRegistry) => {
// get the vehicle
return vehicleRegistry.get(vehicle.$identifier);
})
.then((newVehicle) => {
// check that the buyer now owns the car
newVehicle.owner.getIdentifier().should.equal(buyer.$identifier);
});
});
});

2. Animal Tracking Network

Animal Tracking Network

Farmers can move animals between farms/fields and the UK government farming regulator has visibility into the locations of all animals and all animal movements between farms.

Participants: Farmer Regulator

Assets: Animal Business Field

Transactions: AnimalMovementDeparture AnimalMovementArrival SetupDemo

animal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
describe('#setupDemo', () => {
it('should create the correct number of resources in the network', () => {
// Transaction is run in before
return businessNetworkConnection.getAssetRegistry(namespace + '.Animal')
.then((ar) => {
return ar.getAll();
})
.then((animals) => {
animals.length.should.equal(8);

return businessNetworkConnection.getParticipantRegistry(namespace + '.Farmer');
})
.then((pr) => {
return pr.getAll();
})
.then((farmers) => {
farmers.length.should.equal(2);
return businessNetworkConnection.getAssetRegistry(namespace + '.Business');
})
.then((ar) => {
return ar.getAll();
})
.then((businesses) => {
businesses.length.should.equal(2);
return businessNetworkConnection.getAssetRegistry(namespace + '.Field');
})
.then((ar) => {
return ar.getAll();
})
.then((fields) => {
fields.length.should.equal(4);
});
});
});

describe('#onAnimalMovementDeparture', function() {

it('should change an animal to IN_TRANSIT and add it to receiving business', function() {
return runAnimalMovementDepartureAndGetAnimal()
.then((animal) => {
animal.movementStatus.should.equal('IN_TRANSIT');

return businessNetworkConnection.getAssetRegistry(namespace + '.Business');
})
.then((ar) => {
return ar.get('BUSINESS_2');
})
.then((business) => {
business.incomingAnimals[0].getIdentifier().should.equal('ANIMAL_1');
});
});

it('should fail if the animal is not IN_FIELD', () => {
const transaction = factory.newTransaction(namespace, 'AnimalMovementDeparture');
transaction.animal = factory.newRelationship(namespace, 'Animal', 'ANIMAL_1');
transaction.from = factory.newRelationship(namespace, 'Business', 'BUSINESS_1');
transaction.to = factory.newRelationship(namespace, 'Business', 'BUSINESS_2');
transaction.fromField = factory.newRelationship(namespace, 'Field', 'FIELD_1');

return businessNetworkConnection.submitTransaction(transaction)
.catch((err) => {
err.message.should.equal('Animal is already IN_TRANSIT');
});
});
});

describe('#onAnimalMovementArrival', () => {
it('should change an animal to IN_FIELD and change its owner, location and remove it from incoming animals', () => {
let animalId;
return runAnimalMovementDepartureAndGetAnimal()
.then(animal => {
animalId = animal.getIdentifier();
const transaction = factory.newTransaction(namespace, 'AnimalMovementArrival');
transaction.animal = factory.newRelationship(namespace, 'Animal', animalId);
transaction.from = factory.newRelationship(namespace, 'Business', 'BUSINESS_1');
transaction.to = factory.newRelationship(namespace, 'Business', 'BUSINESS_2');
transaction.arrivalField = factory.newRelationship(namespace, 'Field', 'FIELD_2');

return businessNetworkConnection.submitTransaction(transaction);
})
.then(() => {
return businessNetworkConnection.getAssetRegistry(namespace + '.Animal');
})
.then((ar) => {
return ar.get(animalId);
})
.then((animal) => {
animal.movementStatus.should.equal('IN_FIELD');
animal.owner.getIdentifier().should.equal('FARMER_2');
animal.location.getIdentifier().should.equal('FIELD_2');

return businessNetworkConnection.getAssetRegistry(namespace + '.Business');
})
.then((ar) => {
return ar.get('BUSINESS_2');
})
.then((business) => {
business.incomingAnimals.forEach((animal) => {
animal.getIdentifier().should.not.equal(animalId);
});
});
});
});

3. Digital Property Network

Digital Property Network

This Defines a business network where house sellers can list their properties for sale.

Participants: Person

Assets: LandTitle SalesAgreement

Transactions: RegisterPropertyForSale

digital house sellers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
describe('#onRegisterPropertyForSale', () => {

it('should change the forSale flag from undefined to true', () => {

// Create the existing LandTitle asset.
let factory = businessNetworkConnection.getBusinessNetwork().getFactory();

let seller = factory.newResource('net.biz.digitalPropertyNetwork', 'Person', 'P1');
seller. firstName = 'Dan';
seller.lastName = 'Selman';

let landTitle = factory.newResource('net.biz.digitalPropertyNetwork', 'LandTitle', 'TITLE_1');
let person = factory.newRelationship('net.biz.digitalPropertyNetwork', 'Person', 'P1');
landTitle.owner = person;
landTitle.information = 'Some information';
landTitle.forSale = false;

// Create the transaction.
let transaction = factory.newTransaction('net.biz.digitalPropertyNetwork', 'RegisterPropertyForSale');
transaction.title = factory.newRelationship('net.biz.digitalPropertyNetwork', 'LandTitle', 'TITLE_1');
transaction.seller = person;

// Get the asset registry.
return businessNetworkConnection.getParticipantRegistry('net.biz.digitalPropertyNetwork.Person')
.then((personRegistry) => {
return personRegistry.add(seller);
})
.then(() => {
return businessNetworkConnection.getAssetRegistry('net.biz.digitalPropertyNetwork.LandTitle');
})
.then((assetRegistry) => {
// Add the LandTitle asset to the asset registry.
return assetRegistry.add(landTitle);
})
.then(() => {
// Submit the transaction.
return businessNetworkConnection.submitTransaction(transaction);

})
.then(() => {
return businessNetworkConnection.getAssetRegistry('net.biz.digitalPropertyNetwork.LandTitle');
})
.then((assetRegistry) => {
// Get the modified land title.
return assetRegistry.get('TITLE_1');
})
.then((modifiedLandTitle) => {
// Ensure the LandTitle has been modified correctly.
modifiedLandTitle.forSale.should.be.true;
});
});
});

4. Marbles Network

Marbles Network

This is an interactive and distributed, marble trading demo. List marbles for sale and exchange marbles between participants.

Participants: Player

Assets: Marble

Transactions: TradeMarble

此处输入图片的描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
describe('#trade', () => {

it('should be able to trade marbles', () => {

const factory = businessNetworkConnection.getBusinessNetwork().getFactory();

// create the first player
const dan = factory.newResource(namespace, 'Player', 'daniel.selman@example.com');
dan.firstName = 'Dan';
dan.lastName = 'Selman';

// create the marble
const marble = factory.newResource(namespace, 'Marble', 'MARBLE_001');
marble.size = 'SMALL';
marble.color = 'RED';
marble.owner = factory.newRelationship(namespace, 'Player', dan.$identifier);

// create the second player
const simon = factory.newResource(namespace, 'Player', 'sstone1@example.com');
simon.firstName = 'Simon';
simon.lastName = 'Stone';

const tradeMarble = factory.newTransaction(namespace, 'TradeMarble');
tradeMarble.newOwner = factory.newRelationship(namespace, 'Player', simon.$identifier);
tradeMarble.marble = factory.newRelationship(namespace, 'Marble', marble.$identifier);

// Get the asset registry.
return businessNetworkConnection.getAssetRegistry(namespace + '.Marble')
.then((marbleRegistry) => {

// Add the Marble to the asset registry.
return marbleRegistry.add(marble)
.then(() => {
return businessNetworkConnection.getParticipantRegistry(namespace + '.Player');
})
.then((playerRegistry) => {
// add the players
return playerRegistry.addAll([dan, simon]);
})
.then(() => {
// submit the transaction
return businessNetworkConnection.submitTransaction(tradeMarble);
})
.then(() => {
return businessNetworkConnection.getAssetRegistry(namespace + '.Marble');
})
.then((marbleRegistry) => {
// get the listing
return marbleRegistry.get(marble.$identifier);
})
.then((newMarble) => {
// simon should now own the marble
newMarble.owner.getIdentifier().should.equal('sstone1@example.com');
});
});
});
});